package com.suning.sawp.web.controller;

import java.security.Principal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.google.common.base.Function;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.suning.sawp.constants.ClerkConstants;
import com.suning.sawp.constants.ErrorCodeConstants;
import com.suning.sawp.constants.LoggerConstants;
import com.suning.sawp.dto.bi.StoreRetGdsRankListDto;
import com.suning.sawp.dto.common.ReturnMsg;
import com.suning.sawp.dto.mainpush.StoreManDto;
import com.suning.sawp.dto.returngoods.BrandStatis;
import com.suning.sawp.dto.returngoods.CockpitHomeDto;
import com.suning.sawp.dto.returngoods.OosCateBrandStatis;
import com.suning.sawp.dto.returngoods.OosStatisDetailRtn;
import com.suning.sawp.dto.returngoods.RetGdsRateChartRtn;
import com.suning.sawp.dto.returngoods.RetGdsStatisRtn;
import com.suning.sawp.dto.returngoods.StoreOosHomeShowDto;
import com.suning.sawp.dto.storeman.Category;
import com.suning.sawp.dto.yxwt.CateInfo;
import com.suning.sawp.intf.model.ModelAnalyseService;
import com.suning.sawp.intf.returngoods.ReturnGoodsService;
import com.suning.sawp.intf.returngoods.StoreOosService;
import com.suning.sawp.intf.storeman.StoreManService;
import com.suning.sawp.intf.yxwt.SaledNoTakeService;
import com.suning.sawp.po.bi.BiStoreRetGdsHomeVo;
import com.suning.sawp.service.branch.BranchRetStatis;
import com.suning.sawp.service.branch.BranchRetStatisService;
import com.suning.sawp.service.impl.bi.BiStoreRetGdsHomeService;
import com.suning.sawp.service.util.DateUtils;
import com.suning.sawp.web.exception.MyGsonView;

/**
 * 
 * 退货统计(驾驶舱模块)<br>
 * 〈功能详细描述〉 退货、缺货
 * 
 * @author Wuxiao
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
@Controller
@RequestMapping("/returnGoods")
public class ReturnGoodsController extends DjBaseController {

    /**
     * 日志
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(LoggerConstants.SAWP_SERVICE);

    /**
     * 退货服务
     */
    @Resource
    ReturnGoodsService returnGoodsService;

    /**
     * 店员服务
     */
    @Autowired
    StoreManService storeManService;

    /**
     * BI服务
     */
    @Autowired
    BiStoreRetGdsHomeService biStoreRetGdsHomeService;

    /**
     * 品牌统计日服务
     */
    @Autowired
    BranchRetStatisService branchRetStatisServiceDay;

    /**
     * 品牌统计月服务
     */
    @Autowired
    BranchRetStatisService branchRetStatisServiceMonth;

    /**
     * 品牌统计周服务
     */
    @Autowired
    BranchRetStatisService branchRetStatisServiceWeek;

    /**
     * 缺货服务
     */
    @Resource
    StoreOosService storeOosService;

    /**
     * 样机分析服务
     */
    @Autowired
    ModelAnalyseService modelAnalyseService;

    @Autowired
    SaledNoTakeService saledNoTakeService;

    /**
     * 
     * 功能描述: 店+退货首页接口<br>
     * 〈功能详细描述〉
     *
     * @param principal
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @SuppressWarnings("unchecked")
    @RequestMapping("/home.do")
    public MyGsonView queryReturnGoodsHome(Principal principal) {
        // 工号
        String staffId = principal.getName();
        StoreManDto storeMan = storeManService.queryStoreManAttachInfo(staffId);
        ReturnMsg<CockpitHomeDto> returnMsg = new ReturnMsg<CockpitHomeDto>();
        CockpitHomeDto cockpitHomeDto = new CockpitHomeDto();
        // 查询退货首页数据
        ReturnMsg<Map<String, Object>> result = biStoreRetGdsHomeService.queryRetGdsHomeInfo(storeMan);
        if (ReturnMsg.SUCCESS.equals(result.getRetFlag())) {
            Map<String, Object> map = result.getData();
            cockpitHomeDto.setRefundInfo((List<BiStoreRetGdsHomeVo>) map.get("refundInfo"));
            cockpitHomeDto.setThreeProfitEntranceUrl((String) map.get("threeProfitEntranceUrl"));
            cockpitHomeDto.setThreeProfitErrorUrl((String) map.get("threeProfitErrorUrl"));
            cockpitHomeDto.setThreeProfitUrl((String) map.get("threeProfitUrl"));
        }
        // 查询缺货首页数据
        ReturnMsg<List<StoreOosHomeShowDto>> oosResult = storeOosService.queryOosHomeDataShow(staffId);
        // 组装两块数据
        if (ReturnMsg.SUCCESS.equals(oosResult.getRetFlag())) {
            cockpitHomeDto.setOos(oosResult.getData());
        }

        // 查询已销未提首页数据
        ReturnMsg<List<CateInfo>> cateList = saledNoTakeService.queryCateInfoByCateCodeList(storeMan);
        // 组装两块数据
        if (cateList != null && ReturnMsg.SUCCESS.equals(oosResult.getRetFlag())) {
            cockpitHomeDto.setCateList(cateList.getData());
        } else {
            LOGGER.error("queryReturnGoodsHome saledNoTakeService.queryCateInfoByCateCodeList error for storeMan :  "
                    + storeMan);
        }

        // 统计日期-取昨天日期
        String statisDate = DateUtils.getDateStrByFormat(DateUtils.getNextDay(new Date(), -1),
                DateUtils.DEFAULT_DATE_PATTERN);
        cockpitHomeDto.setStatisDate(statisDate);

        // 查询样机汇总贡献率
        // 1. 判断店员是店长，还是督导
        if (ClerkConstants.STORE_KEEPER.equals(storeMan.getPositionId())) {
            // 查询并设置店长总贡献率
            cockpitHomeDto
                    .setContributions(modelAnalyseService.querySummaryContribution(storeMan.getStoreCode(), null));
        } else if (ClerkConstants.SALE_GUIDE.equals(storeMan.getPositionId())) {
            // 转换下品类数组
            if (CollectionUtils.isNotEmpty(storeMan.getCategories())) {
                // 转换结果数据
                cockpitHomeDto.setContributions(modelAnalyseService.querySummaryContribution(storeMan.getStoreCode(),
                        storeMan.getCategories()));
            }
        }
        // 封装结果
        returnMsg.setData(cockpitHomeDto);
        return setGsonView(returnMsg);
    }

    /**
     * 
     * 功能描述: 退货统计<br>
     * 〈功能详细描述〉
     * 
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @RequestMapping("/statisDate.do")
    public MyGsonView statisDate(String categoryCode, String queryType, Principal principal) {
        ReturnMsg<List<RetGdsRateChartRtn>> ret = new ReturnMsg<List<RetGdsRateChartRtn>>();
        try {
            ret = returnGoodsService.queryRtnGdsChart(principal.getName(), categoryCode, queryType);
        } catch (Exception e) {
            ret.setError(ErrorCodeConstants.ERR_0002);
            LOGGER.error(String.format("退货统计图表查询异常 input param categoryCode:%s,queryType :%s", categoryCode, queryType),
                    e);
        }
        return setGsonView(ret);
    }

    /**
     * 
     * 功能描述: 退货明细<br>
     * 〈功能详细描述〉
     * 
     * @param branchCodes
     * @param categoryCode
     * @param limit
     * @param startIndex
     * @param queryType
     * @param sortType
     * @param sumType
     * @param principal
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @RequestMapping("/statisDetail.do")
    public MyGsonView statisDetail(String branchCodes, String categoryCode, Integer limit, Integer startIndex,
            String queryType, String sortType, String sumType, Principal principal) {
        ReturnMsg<RetGdsStatisRtn> ret = new ReturnMsg<RetGdsStatisRtn>();
        try {
            ret = returnGoodsService.queryRetGdsDetail(principal.getName(), branchCodes, categoryCode, limit,
                    startIndex, queryType, sortType, sumType);
        } catch (Exception e) {
            ret.setError(ErrorCodeConstants.ERR_0002);
            LOGGER.error(String.format(
                    "退货品牌或品类详细查询异常 input param branchCodes:%s,categoryCode:%s,queryType:%s,sortType:%s,sumType:%s",
                    branchCodes, categoryCode, queryType, sortType, sumType), e);
        }
        return setGsonView(ret);
    }

    /**
     * 
     * 功能描述: 查询门店退货排行榜<br>
     * 〈功能详细描述〉
     *
     * @param principal
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @RequestMapping("/getStoreRetGdsRankList.do")
    public MyGsonView getStoreRetGdsRankList(Principal principal, String categoryCode) {
        ReturnMsg<List<StoreRetGdsRankListDto>> retMsg = returnGoodsService.getStoreRetGdsRankList(principal.getName(),
                categoryCode);
        return setGsonView(retMsg);
    }

    /**
     * 品牌退货日统计(昨天)
     * 
     * @param categoryCodes 品类编码
     * @param principal
     * @return
     */
    @RequestMapping(value = "/branchRetStatis.do", params = { "queryType=0" })
    public MyGsonView queryByDay(@RequestParam(defaultValue = "") String[] categoryCodes,
            @RequestParam(value = "offset", defaultValue = "-1") int offset, Principal principal) {
        ReturnMsg<BranchRetStatis> ret = query(principal, categoryCodes, offset, new CategoryCodeValidatorWraper() {
            @Override
            public BranchRetStatis query(String storeCode, String[] categoryCodes, int offset) {
                return branchRetStatisServiceDay.queryStatis(storeCode, categoryCodes, offset);
            }
        });
        return setGsonView(ret);
    }

    /**
     * 品牌退货月统计(本周)
     * 
     * @param categoryCodes 品类编码
     * @param principal
     * @return
     */
    @RequestMapping(value = "/branchRetStatis.do", params = { "queryType=1" })
    public MyGsonView queryByWeek(@RequestParam(defaultValue = "") String[] categoryCodes,
            @RequestParam(value = "offset", defaultValue = "-1") int offset, Principal principal) {
        ReturnMsg<BranchRetStatis> ret = query(principal, categoryCodes, offset, new CategoryCodeValidatorWraper() {
            @Override
            public BranchRetStatis query(String storeCode, String[] categoryCodes, int offset) {
                return branchRetStatisServiceWeek.queryStatis(storeCode, categoryCodes, offset);
            }
        });
        return setGsonView(ret);
    }

    /**
     * 品牌退货月统计(当月)
     * 
     * 
     * 
     * @param categoryCodes 品类编码
     * @param principal
     * @return
     */
    @RequestMapping(value = "/branchRetStatis.do", params = { "queryType=2" })
    public MyGsonView queryByMonth(@RequestParam(defaultValue = "") String[] categoryCodes,
            @RequestParam(value = "offset", defaultValue = "-1") int offset, Principal principal) {
        ReturnMsg<BranchRetStatis> ret = query(principal, categoryCodes, offset, new CategoryCodeValidatorWraper() {
            @Override
            public BranchRetStatis query(String storeCode, String[] categoryCodes, int offset) {
                return branchRetStatisServiceMonth.queryStatis(storeCode, categoryCodes, offset);
            }
        });
        return setGsonView(ret);
    }

    private interface CategoryCodeValidatorWraper {
        BranchRetStatis query(String storeCode, String[] categoryCodes, int offset);
    }

    /**
     * 查询业务逻辑处理类
     * 
     * @param principal
     * @param categoryCodes
     * @param offset
     * @param categoryCodeValidatorWraper
     * @return
     */
    private ReturnMsg<BranchRetStatis> query(Principal principal, String[] categoryCodes, int offset,
            CategoryCodeValidatorWraper categoryCodeValidatorWraper) {
        ReturnMsg<BranchRetStatis> ret = new ReturnMsg<BranchRetStatis>();
        StoreManDto storeManDto = storeManService.queryStoreManAttachInfo(principal.getName());
        String storeCode = storeManDto.getStoreCode();
        BranchRetStatis result = null;
        if (ClerkConstants.STORE_KEEPER.equals(storeManDto.getPositionId())) {
            // 店长
            result = categoryCodeValidatorWraper.query(storeCode, categoryCodes, offset);
            // 品类处理
            if (null != result) {
                result.setCategories(storeManDto.getCategories());
            }
        } else if (ClerkConstants.SALE_GUIDE.equals(storeManDto.getPositionId())) {
            // 督导
            Set<String> alls = Sets
                    .newHashSet(Lists.transform(storeManDto.getCategories(), new Function<Category, String>() {
                        @Override
                        public String apply(Category input) {
                            return input.getCategoryCode();
                        }
                    }));
            alls.retainAll(Sets.newHashSet(categoryCodes));
            if (alls.isEmpty()) {
                ret.setError("Error", "没有传品类或者无该品类查询权限");
            } else {
                result = categoryCodeValidatorWraper.query(storeCode, Iterables.toArray(alls, String.class), offset);
                // 品类处理
                if (null != result) {
                    result.setCategories(storeManDto.getCategories());
                }
            }
        } else {
            ret.setError("Error", String.format("%s of %s,%s,无权限操作", principal.getName(), storeManDto.getStoreCode(),
                    storeManDto.getPositionId()));
        }
        ret.setData(result);
        return ret;

    }

    /**
     * 
     * 功能描述: 缺货品牌列表<br>
     * 〈功能详细描述〉
     *
     * @param categoryCode
     * @param queryType
     * @param principal
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @RequestMapping("/oos/brandList.do")
    public MyGsonView oosBrandList(String categoryCodes, String queryType, Principal principal) {
        ReturnMsg<BrandStatis> retMsg = storeOosService.queryOosBrandList(principal.getName(), categoryCodes,
                queryType);
        return setGsonView(retMsg);
    }

    /**
     * 
     * 功能描述: 缺货统计列表<br>
     * 〈功能详细描述〉
     *
     * @param brandCodes 品牌编码9位集 多个“,”隔开
     * @param categoryCodes 品类编码集 多个“,”隔开
     * @param limit
     * @param queryType 查询类型 1-整体缺货；2-主推缺货；3-热销缺货
     * @param startIndex
     * @param sumType 汇总类型 1-汇总展示；0-不汇总
     * @param principal
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @RequestMapping("/oos/statisList.do")
    public MyGsonView oosStatisList(String brandCodes, String categoryCodes, int limit, String queryType,
            int startIndex, String sumType, Principal principal) {
        ReturnMsg<List<OosCateBrandStatis>> retMsg = storeOosService.queryOosStatisList(brandCodes, categoryCodes,
                limit, queryType, startIndex, sumType, principal.getName());
        return setGsonView(retMsg);
    }

    /**
     * 
     * 功能描述: 缺货商品明细列表<br>
     * 〈功能详细描述〉
     *
     * @param commKeyword
     * @param brandCodes
     * @param categoryCodes
     * @param limit
     * @param queryType
     * @param sortType
     * @param startIndex
     * @param principal
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    @RequestMapping("/oos/statisDetail.do")
    public MyGsonView oosStatisDetail(String commKeyword, String brandCodes, String categoryCodes, int limit,
            String queryType, String sortType, int startIndex, Principal principal) {
        ReturnMsg<List<OosStatisDetailRtn>> retMsg = storeOosService.queryOosStatisDetails(commKeyword, brandCodes,
                categoryCodes, limit, queryType, sortType, startIndex, principal.getName());
        return setGsonView(retMsg);
    }
}
